#include <QSqlQuery>
#include <QSqlRecord>
#include <QVariant>
#include <QMessageBox>
#include <QDebug>
#include <math.h>

#include "goaldao.h"


MoneyGoal::goal_types selectTypeGoal(int typeGoal)
{
    switch(typeGoal) {
    case 0:
        return MoneyGoal::IN_greater_than;
        break;
    case 1:
        return MoneyGoal::OUT_less_than;
        break;
    case 2:
        return MoneyGoal::Total_greater_than;
        break;
    }

    return MoneyGoal::Total_greater_than;
}

int selectTypeGoal(MoneyGoal::goal_types typeGoal)
{
    if (typeGoal == MoneyGoal::IN_greater_than)
        return 0;
    else if (typeGoal == MoneyGoal::OUT_less_than)
        return 1;

    return 2;
}

MoneyGoal* getPercentageByGoal(MoneyGoal* goal, int id_user)
{
    if (!goal)
        return 0;

    int percentage = 0;
    QString goalType = "";
    if (goal->getTypeGoal() == MoneyGoal::IN_greater_than)
        goalType = " AND m1.type_money = 0";
    else if (goal->getTypeGoal() == MoneyGoal::OUT_less_than)
        goalType = " AND m1.type_money = 1";
    QString strQuery = " SELECT SUM(m1.amount) as total FROM money m1 "
                       " WHERE m1.id_user = :id_user AND m1.dt_transaction >= :dt_since "
                       " AND m1.dt_transaction <= :dt_until " + goalType;

    QSqlQuery query;
    query.prepare(strQuery);
    query.bindValue(":id_user", id_user);
    query.bindValue(":dt_since", goal->getDtInitial());
    query.bindValue(":dt_until", goal->getDtFinal());
    query.exec();

    if (query.next()) {
        float total = query.value(query.record().indexOf("total")).toFloat();
        if (goal->target() != 0)
            percentage = floor(100 *  total / goal->target());
        if (percentage < 0)
            percentage = 0;
        else if (percentage > 100)
            percentage = 100;
        qDebug() << __PRETTY_FUNCTION__ << "Setting percentage" << percentage << total << goal->target();
    }

    goal->setPercentage(percentage);

    return goal;
}

QList<MoneyGoal*> getAllMoneyGoal(int id_user)
{

    qDebug() << __PRETTY_FUNCTION__;

    QString strQuery = " SELECT id_goal, dt_initial, dt_final, target_value, type_goal, description as"
                       " id_goal, dt_initial, dt_final, target_value, type_goal, description FROM ";
    strQuery = strQuery + " goal where id_user = :id_user ";

    QSqlQuery query(strQuery);
    query.bindValue(":id_user", id_user);

    QList<MoneyGoal*> listMoneyGoal;
    query.exec();
    while (query.next()) {
        MoneyGoal *goal = new MoneyGoal(query.value(query.record().indexOf("id_goal")).toInt(),
                                   selectTypeGoal(query.value(query.record().indexOf("type_goal")).toInt()),
                                    query.value(query.record().indexOf("target_value")).toFloat(),
                                    query.value(query.record().indexOf("dt_initial")).toDate(),
                                    query.value(query.record().indexOf("dt_final")).toDate(),
                                    query.value(query.record().indexOf("description")).toString());

        goal = getPercentageByGoal(goal, id_user);

        listMoneyGoal.append(goal);
    }

    return listMoneyGoal;
}

bool deleteMoneyGoal(MoneyGoal* goal)
{
    qDebug() << __PRETTY_FUNCTION__;

    if (!goal)
        return false;

    QString strQuery = " DELETE FROM ";
    strQuery = strQuery + " goal WHERE id_goal = :id_goal";

    QSqlQuery query;
    query.prepare(strQuery);
    query.bindValue(":id_goal", goal->getId());
    return query.exec();
}

bool updateMoneyGoal(MoneyGoal* goal)
{
    qDebug() << __PRETTY_FUNCTION__;

    if (!goal)
        return false;

    QString strQuery = " UPDATE goal SET dt_initial = :dt_initial, dt_final = :dt_final, "
                       " type_goal = :type_goal, target_value = :target_value, description = :description "
                       " WHERE id_goal = :id_goal";


    QSqlQuery query;
    query.prepare(strQuery);
    query.bindValue(":id_goal", goal->getId());
    query.bindValue(":dt_initial", goal->getDtInitial());
    query.bindValue(":dt_final", goal->getDtFinal());
    query.bindValue(":type_goal", selectTypeGoal(goal->getTypeGoal()));
    query.bindValue(":target_value", goal->getTarget());
    query.bindValue(":description", goal->description());

    return query.exec();
}

bool registerMoneyGoal(MoneyGoal* goal, int id_user)
{
    qDebug() << __PRETTY_FUNCTION__;

    if (!goal)
        return false;

    QString strQuery = " INSERT INTO goal (dt_initial, dt_final, type_goal, target_value, description, id_user) "
                       " values (:dt_initial, :dt_final, :type_goal, :target_value, :description, :id_user) ";

    qDebug() << strQuery << id_user;

    QSqlQuery query;
    query.prepare(strQuery);
    query.bindValue(":dt_initial", goal->getDtInitial());
    query.bindValue(":dt_final", goal->getDtFinal());
    query.bindValue(":type_goal", selectTypeGoal(goal->getTypeGoal()));
    query.bindValue(":target", goal->getTarget());
    query.bindValue(":description", goal->description());
    query.bindValue(":id_user", id_user);

    return query.exec();
}


MoneyGoal* getGoal(MoneyGoal *incomplete_goal, int id_user)
{
    qDebug() << __PRETTY_FUNCTION__;

    QString strQuery = " SELECT id_goal, dt_initial, dt_final, target_value, type_goal, description as "
                       " id_goal, dt_initial, dt_final, target_value, type_goal, description FROM      "
                       " goal where id_user = :id_user AND dt_initial = :dt_initial       "
                       " AND dt_final = :dt_final AND target_value = :target_value        "
                       " AND type_goal = :type_goal AND description LIKE :description     ";

    QSqlQuery query;
    query.prepare(strQuery);
    query.bindValue(":id_user", id_user);
    query.bindValue(":dt_initial", incomplete_goal->getDtInitial());
    query.bindValue(":dt_final", incomplete_goal->getDtFinal());
    query.bindValue(":type_goal", selectTypeGoal(incomplete_goal->getTypeGoal()));
    query.bindValue(":target_value", incomplete_goal->getTarget());
    query.bindValue(":description", incomplete_goal->description());

//    QString strQueryTranslated;
//    strQueryTranslated = strQuery.replace(":id_user", QString::number(id_user));
//    strQueryTranslated = strQuery.replace(":dt_initial", incomplete_goal->initialDate());
//    strQueryTranslated = strQuery.replace(":dt_final", incomplete_goal->finalDate());
//    strQueryTranslated = strQuery.replace(":type_goal", QString::number(selectTypeGoal(incomplete_goal->getTypeGoal())));
//    strQueryTranslated = strQuery.replace(":target_value", QString::number(incomplete_goal->getTarget()));
//    strQueryTranslated = strQuery.replace(":description", incomplete_goal->description());

//    qDebug() << __PRETTY_FUNCTION__ << strQueryTranslated;

//    qDebug() << __PRETTY_FUNCTION__ << strQuery;
//    qDebug() << __PRETTY_FUNCTION__ << "Id User" << id_user;
//    qDebug() << __PRETTY_FUNCTION__ << "Dt initial" << incomplete_goal->getDtInitial();
//    qDebug() << __PRETTY_FUNCTION__ << "Dt Final" << incomplete_goal->getDtFinal();
//    qDebug() << __PRETTY_FUNCTION__ << "Target" << incomplete_goal->getTarget();
//    qDebug() << __PRETTY_FUNCTION__ << "Description" << incomplete_goal->description();
//    qDebug() << __PRETTY_FUNCTION__ << "GoalType" << selectTypeGoal(incomplete_goal->getTypeGoal());


    MoneyGoal* goal = 0;
    query.exec();
    if (query.next()) {
        goal = new MoneyGoal(query.value(query.record().indexOf("id_goal")).toInt(),
                                   selectTypeGoal(query.value(query.record().indexOf("type_goal")).toInt()),
                                    query.value(query.record().indexOf("target_value")).toFloat(),
                                    query.value(query.record().indexOf("dt_initial")).toDate(),
                                    query.value(query.record().indexOf("dt_final")).toDate(),
                                    query.value(query.record().indexOf("description")).toString());
    } else qDebug() << __PRETTY_FUNCTION__ << "Goal not found";

    return goal;
}
